package com.webserver.core;

import com.webserver.http.HttpServletRequest;
import com.webserver.http.HttpServletResponse;

import java.io.File;
import java.lang.reflect.Method;
import java.net.URISyntaxException;

/**
 * DispatcherServlet实际是由SpringMVC框架提供的一个类，用于和Tomcat整合并负责
 * 接手处理请求的工作
 * <p>
 * Servlet是Java EE里的一个接口，运行在服务端的小程序
 * 有一个抽象方法用于处理某个事务
 * public void service(HttpServletRequest request, HttpServletResponse response)
 * <p>
 * SpringMVC框架提供的DispatcherServlet就实现了该接口并重写了service方法，与Tomcat整合后，
 * Tomcat在处理请求的环节的环节就可以和调用DispatcherServlet的service方法将请求对象与响应对象传递进去
 * 由SpringMVC框架完成处理请求的操作。
 *
 * @author Chen
 */
public class DispatcherServlet {
    private static DispatcherServlet instance = new DispatcherServlet();
    private static File root;
    private static File staticDir;

    static {
        try {
            root = new File(DispatcherServlet.class.getClassLoader().getResource(".").toURI());
            staticDir = new File(root, "static");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

    private DispatcherServlet() {
    }

    public static DispatcherServlet getInstance() {
        return instance;
    }

    public void service(HttpServletRequest request, HttpServletResponse response) {
        // 判断用户的请求路径不应当含有参数部分，所以uri不适用
        String path = request.getRequestURI();
        System.out.println("抽象路径：" + path);

        // 当前请求路径是否对应为一个业务处理
        try {
            Method method = HandlerMapping.getMethod(path);
            if (method != null) {
                Class<?> clazz = method.getDeclaringClass();
                Object obj = clazz.newInstance();
                method.invoke(obj, request, response);
                return;
            }
        } catch (Exception e) {
            // 处理业务如果出现了异常应当设置response响应500类错误
            response.setStatusCode(500);
            response.setStatusReason("Internal Server Error");
            response.setContentFile(new File(staticDir, "500.html"));
        }

        File contentFile = new File(staticDir, path);
        // 判断请求的文件真实存在且确定是一个文件
        if (!contentFile.isFile()) {
            response.setStatusCode(404);
            response.setStatusReason("NotFound");
            response.setContentFile(new File(staticDir, "404.html"));
        } else {
            response.setContentFile(contentFile);
        }
        response.addHeader("Server", "BirdServer");
    }
}
